package com.saya.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;

public class Utils {
	private static DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

	  private static MemcacheService keycache = MemcacheServiceFactory.getMemcacheService();

	  public static Boolean checkPhoneNumber(String phonenumber) {
	    String patterNumber = "09\\d{8}|\\01d{9}";
	    Pattern pattern = Pattern.compile(patterNumber);
	    Matcher matcher = pattern.matcher(phonenumber);
	    return Boolean.valueOf(matcher.matches());
	  }

	  public static Boolean checkEmail(String email)
	  {
	    Pattern pattern = Pattern.compile("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");
	    Matcher matcher = pattern.matcher(email);
	    return Boolean.valueOf(matcher.matches());
	  }

	  public static String getCurrentDate()
	  {
	    String timeStamp = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
	      .format(Calendar.getInstance().getTime());
	    return timeStamp;
	  }

	  public static String getMD5(String plaintext) throws NoSuchAlgorithmException
	  {
	    MessageDigest m = MessageDigest.getInstance("MD5");
	    m.reset();
	    m.update(plaintext.getBytes());
	    byte[] digest = m.digest();
	    BigInteger bigInt = new BigInteger(1, digest);
	    String hashtext = bigInt.toString(16);

	    while (hashtext.length() < 32) {
	      hashtext = "0" + hashtext;
	    }
	    return hashtext;
	  }

	  public static DatastoreService getDatastoreServiceInstance() {
	    return datastore;
	  }

	  public static Entity findEntity(Key key) {
	    try {
	      Entity entity = getFromCache(key);
	      if (entity != null) {
	        return entity;
	      }
	      return getDatastoreServiceInstance().get(key); } catch (EntityNotFoundException e) {
	    }
	    return null;
	  }

	  public static Entity getFromCache(Key key)
	  {
	    return (Entity)keycache.get(key);
	  }

	  public static Entity getEntity(String kind, String name) {
	    Key key = KeyFactory.createKey(kind, name);
	    return findEntity(key);
	  }

	  public static Entity getEntity(String kind, long id) {
	    Key key = KeyFactory.createKey(kind, id);
	    System.out.println(key.getId() + " " + key.getKind());
	    return findEntity(key);
	  }

	  public static Entity getEntity(String strkey) {
	    Key key = getKey(strkey);
	    return findEntity(key);
	  }

	  public static Iterable<Entity> listEntities(String kind, String searchBy, String searchFor)
	  {
	    Query query = new Query(kind);
	    if ((searchFor != null) && (!"".equals(searchFor))) {
	      query.addFilter(searchBy, Query.FilterOperator.EQUAL, searchFor);
	    }
	    PreparedQuery pq = datastore.prepare(query);
	    return pq.asIterable();
	  }

	  public static Key persistEntity(Entity entity)
	  {
	    Key key = entity.getKey();
	    Transaction txn = datastore.beginTransaction();
	    try {
	      key = datastore.put(entity);
	      txn.commit();
	    } finally {
	      if (txn.isActive())
	        txn.rollback();
	      else {
	        addToCache(key, entity);
	      }
	    }
	    return key;
	  }

	  public static void addToCache(Key key, Entity entity) {
	    keycache.put(key, entity);
	  }

	  public static void deleteFromCache(Key key)
	  {
	    keycache.delete(key);
	  }

	  public static Iterable<Entity> listChildren(String kind, Key ancestor, int offset, int limit)
	  {
	    Query query = new Query(kind);
	    query.setAncestor(ancestor);
	    query.addFilter("__key__", Query.FilterOperator.GREATER_THAN, ancestor);
	    PreparedQuery pq = datastore.prepare(query);
	    if ((limit == 0) && (offset == 0)) {
	      return pq.asIterable();
	    }
	    return pq.asIterable(FetchOptions.Builder.withOffset(offset).limit(limit));
	  }

	  public static Key getKey(String kind, String name)
	  {
	    return KeyFactory.createKey(kind, name);
	  }

	  public static Key getKey(String kind, long id) {
	    return KeyFactory.createKey(kind, id);
	  }

	  public static Key getKey(String strkey) {
	    return KeyFactory.stringToKey(strkey);
	  }

	  public static Boolean SentEmail(String email, String name, String subject, String content)
	  {
	    Boolean result = Boolean.valueOf(true);
	    Properties props = new Properties();
	    Session session = Session.getDefaultInstance(props, null);

	    System.out.println(email + name + subject + content + "sayavn2013@gmail.com");
	    try {
	      Message msg = new MimeMessage(session);
	      msg.setFrom(
	        new InternetAddress(email, 
	        name));
	      msg.addRecipient(Message.RecipientType.TO, 
	        new InternetAddress("sayavn2013@gmail.com", "Saya"));
	      msg.setSubject(subject);
	      msg.setText(content);
	      Transport.send(msg);
	    }
	    catch (AddressException e) {
	      result = Boolean.valueOf(false);
	    } catch (MessagingException e) {
	      result = Boolean.valueOf(false);
	    } catch (UnsupportedEncodingException e) {
	      result = Boolean.valueOf(false);
	    }
	    return result;
	  }

	  public static Boolean isNullorEmpty(String str) {
	    if (str == null)
	      return Boolean.valueOf(true);
	    if (str.isEmpty()) {
	      return Boolean.valueOf(true);
	    }
	    return Boolean.valueOf(false);
	  }
}
